const {screen,shell,remote, ipcMain, ipcRenderer, BrowserWindow, app} = require('electron');
const animate = require('./animate');
const Type = require('./type');
const ipc = require('./ipc');
const fs = require('fs');
const ofs = require('original-fs');
const path = require('path');

const LS_SETTING_KEY = 'setting';
const LS_HISTORY_KEY = 'history';
const MAINWINDOW_ANIMATE_DURATION = 200;

let setting = null;
let eventType = {
    SETTING_CHANGE:'setting-change',
    TOGGLE_MAIN_WINDOW_VISIBLE:'toogle-main-window-visible',
    
    OPEN_WINDOW: 'open-window',
    LAUNCH_WINDOW: 'launch-window',
    CM_SEARCH: 'cm-search',
    CM_SEARCH_RESULT: 'cm-search-result',
};

let IsInAsar = null;
let settingFile = process.env.LOCALAPPDATA + '\\JinkoQuickStart\\setting.json';

const core = {
    ET: eventType,
    getMainWindowBounds() {
        const scrWorkArea = screen.getPrimaryDisplay().workArea;
        
        let maxWidth = 720, maxHeight = 580;
        let wndWidth = scrWorkArea.width > maxWidth ? maxWidth : scrWorkArea.width,
            wndHeight = scrWorkArea.height > maxHeight ? maxHeight : scrWorkArea.height,
            x = scrWorkArea.x + (scrWorkArea.width - wndWidth)/2,
            y = scrWorkArea.y + scrWorkArea.height - wndHeight;
        
        x = parseInt(x);
        y = parseInt(y);
        wndWidth = parseInt(wndWidth);
        wndHeight = parseInt(wndHeight);
    
        if(ofs.statSync(app.getAppPath()).isFile()) {
            return {x, y, width:wndWidth, height:wndHeight};
        } else {
            return {x:100, y:0, width:1600, height:1000};
        }
    },
    
    showWindow(win) {
        let windowBounds = core.getMainWindowBounds();
        const {height} = screen.getPrimaryDisplay().workAreaSize;
        win.setBounds({y:height});
        win.show();
        
        animate({
            params: {y:height, o: win.getOpacity()},
            target: {y: windowBounds.y, o:1},
            duration:MAINWINDOW_ANIMATE_DURATION,
            easing: 'ease-out',
            update(params) {
                win.setBounds({y: parseInt(params.y)});
                win.setOpacity(params.o);
            }
        });
        
        this.trigger(this.ET.TOGGLE_MAIN_WINDOW_VISIBLE, {show:true});
        // ipc.srToggleWindowVisiable(win, {show:true});
    },
    
    hideWindow(win) {
        let bounds = win.getBounds();
        const {height} = screen.getPrimaryDisplay().workAreaSize;
        
        animate({
            params: {y:bounds.y, o: win.getOpacity()},
            target: {y: height, o:0},
            duration:MAINWINDOW_ANIMATE_DURATION,
            easing: 'ease-out',
            update(params) {
                win.setBounds({y:parseInt(params.y)});
                win.setOpacity(params.o);
                win.setOpacity(params.o);
            },
            complete() {
                win.hide();
            }
        });
    
        this.trigger(this.ET.TOGGLE_MAIN_WINDOW_VISIBLE, {show:false});
        // ipc.srToggleWindowVisiable(win, {show:false});
    },
    
    saveSetting(setting) {
        let settingStr = JSON.stringify(setting);
        
        let dir = path.dirname(settingFile);
        
        if(!fs.existsSync(dir)) {
            fs.mkdirSync(dir, {recursive: true});
        }
        
        fs.writeFileSync(settingFile, settingStr);
        setting = null;
    },
    
    getSetting() {
        if(setting) {
            return setting;
        }
        
        let result = {};
        
        if(fs.existsSync(settingFile)) {
            let settingStr = fs.readFileSync(settingFile).toString();
            result = JSON.parse(settingStr);
        }
        
        if(!result) {
            result = {};
        }
    
        return Type.legalizeData(result,
            {
                base: {
                    nohide: false,
                },
    
                directories: [],
            },
        );
    },
    
    getHistory() {
        let result = JSON.parse(localStorage.getItem(LS_HISTORY_KEY));
        
        if(!result) {
            return [];
        }
        
        return result;
    },
    
    addHistory(label) {
        let historyData = this.getHistory();
        historyData.unshift(label);
        historyData = [...new Set(historyData)];
        
        if(historyData.length > 50) {
            historyData.pop();
        }
    
        localStorage.setItem(LS_HISTORY_KEY, JSON.stringify(historyData));
    },
    
    getShortcurLinkInfo(file) {
        return shell.readShortcutLink(file);
    },
    
    correctPath(path, parseVar) {
        path = path.replace(/[\\/]+/g, '\\').trim();
        
        if(parseVar) {
            path = core.parseVarPath(path);
        }
        
        return path.toLowerCase();
    },
    
    parseVarPath(path) {
        return path.replace(/%(.*?)%/g, (a,b)=> process.env[b]?process.env[b]:a);
    },
    
    transferMessageKey:'__message',
    
    on(key, callback) {
        if(remote) {
            ipcRenderer.on(key, callback);
        } else {
            ipcMain.on(key, (e, args) => callback(args));
        }
    },
    
    trigger(key, args) {
        if(remote) {
            ipcRenderer.send(key, args);
            ipcRenderer.send(this.transferMessageKey, [key, args]);
        } else {
            let allWindows = BrowserWindow.getAllWindows();
            
            for (let i=0; i<allWindows.length; i++) {
                allWindows[i].webContents.send(key, args);
            }
        }
    },

    isAsarMode() {
        if(IsInAsar !== null) {
            return IsInAsar;
        }

        return IsInAsar = ofs.statSync(remote ? remote.app.getAppPath(): app.getAppPath()).isFile();
    },
    
    isInAsar() {
        // return false;
        if(IsInAsar !== null) {
            return IsInAsar;
        }
        
        return IsInAsar = this.isAsarMode();
    },
    
    deleteFolderRecursive(dirpath) {
        if (ofs.existsSync(dirpath)) {
            ofs.readdirSync(dirpath).forEach((file, index) => {
                let curPath = path.join(dirpath, file);
                if (ofs.statSync(curPath).isDirectory()) { // recurse
                    this.deleteFolderRecursive(curPath);
    
                } else {
                    ofs.unlinkSync(curPath);
                }
            });
            ofs.rmdirSync(dirpath);
        }
    }
};

module.exports = core;
